#define ATLAS_SIZE 512
-typedef struct
-{
- PangoFont *font;
- PangoGlyph glyph;
- guint scale; /* times 1024 */
-} GlyphCacheKey;
-
-typedef struct
-{
- GlyphCacheKey *key;
- GskGLCachedGlyph *value;
- cairo_surface_t *surface;
-} DirtyGlyph;
-
-
static guint glyph_cache_hash (gconstpointer v);
static gboolean glyph_cache_equal (gconstpointer v1,
gconstpointer v2);
atlas->y = 1;
atlas->x = 1;
atlas->image = NULL;
- atlas->num_glyphs = 0;
- atlas->dirty_glyphs = NULL;
return atlas;
}
g_assert (atlas->image->texture_id == 0);
g_free (atlas->image);
}
- g_list_free_full (atlas->dirty_glyphs, dirty_glyph_free);
+
g_free (atlas);
}
if (glyph->surface)
cairo_surface_destroy (glyph->surface);
- g_free (glyph);
}
static void
add_to_cache (GskGLGlyphCache *cache,
- GlyphCacheKey *key,
+ GlyphCacheKey *key,
GskGLCachedGlyph *value)
{
GskGLGlyphAtlas *atlas;
int i;
- DirtyGlyph *dirty;
int width = value->draw_width * key->scale / 1024;
int height = value->draw_height * key->scale / 1024;
value->atlas = atlas;
- dirty = g_new0 (DirtyGlyph, 1);
- dirty->key = key;
- dirty->value = value;
- atlas->dirty_glyphs = g_list_prepend (atlas->dirty_glyphs, dirty);
+ atlas->pending_glyph.key = key;
+ atlas->pending_glyph.value = value;
atlas->x = atlas->x + width + 1;
atlas->y = MAX (atlas->y, atlas->y0 + height + 1);
- atlas->num_glyphs++;
-
#ifdef G_ENABLE_DEBUG
if (GSK_RENDERER_DEBUG_CHECK (cache->renderer, GLYPH_CACHE))
{
for (i = 0; i < cache->atlases->len; i++)
{
atlas = g_ptr_array_index (cache->atlases, i);
- g_print ("\tGskGLGlyphAtlas %d (%dx%d): %d glyphs (%d dirty), %.2g%% old pixels, filled to %d, %d / %d\n",
+ g_print ("\tGskGLGlyphAtlas %d (%dx%d): %.2g%% old pixels, filled to %d, %d / %d\n",
i, atlas->width, atlas->height,
- atlas->num_glyphs, g_list_length (atlas->dirty_glyphs),
100.0 * (double)atlas->old_pixels / (double)(atlas->width * atlas->height),
atlas->x, atlas->y0, atlas->y);
}
}
static void
-upload_dirty_glyphs (GskGLGlyphCache *self,
- GskGLGlyphAtlas *atlas)
+upload_dirty_glyph (GskGLGlyphCache *self,
+ GskGLGlyphAtlas *atlas)
{
- GList *l;
- guint num_regions;
- GskImageRegion *regions;
- int i;
+ GskImageRegion region;
- num_regions = g_list_length (atlas->dirty_glyphs);
- regions = alloca (sizeof (GskImageRegion) * num_regions);
+ g_assert (atlas->pending_glyph.key != NULL);
- for (l = atlas->dirty_glyphs, i = 0; l; l = l->next, i++)
- render_glyph (atlas, (DirtyGlyph *)l->data, ®ions[i]);
+ render_glyph (atlas, &atlas->pending_glyph, ®ion);
- GSK_RENDERER_NOTE (self->renderer, GLYPH_CACHE,
- g_message ("uploading %d glyphs to cache", num_regions));
+ gsk_gl_image_upload_regions (atlas->image, self->gl_driver, 1, ®ion);
-
- gsk_gl_image_upload_regions (atlas->image, self->gl_driver, num_regions, regions);
-
- g_list_free_full (atlas->dirty_glyphs, dirty_glyph_free);
- atlas->dirty_glyphs = NULL;
+ dirty_glyph_free (&atlas->pending_glyph);
+ atlas->pending_glyph.key = NULL;
+ atlas->pending_glyph.value = NULL;
}
const GskGLCachedGlyph *
}
GskGLImage *
-gsk_gl_glyph_cache_get_glyph_image (GskGLGlyphCache *self,
+gsk_gl_glyph_cache_get_glyph_image (GskGLGlyphCache *self,
const GskGLCachedGlyph *glyph)
{
GskGLGlyphAtlas *atlas = glyph->atlas;
g_assert (atlas != NULL);
-
if (atlas->image == NULL)
{
atlas->image = g_new0 (GskGLImage, 1);
gsk_gl_image_create (atlas->image, self->gl_driver, atlas->width, atlas->height);
}
- if (atlas->dirty_glyphs)
- upload_dirty_glyphs (self, atlas);
+ if (atlas->pending_glyph.key != NULL)
+ upload_dirty_glyph (self, atlas);
return atlas->image;
}